home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) Feb. 1999, Matt Conover & w00w00
- *
- * Demonstrates modifying opcodes in binary files. (Broken)
- * To compile: gcc -o bfd bfd.c -lbfd -liberty
- */
-
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdarg.h>
- #include <errno.h>
- #include <ctype.h>
- #include <sys/types.h>
- #include <netinet/in.h>
- #include <bfd.h>
-
- #if defined(SUN) || defined(SOLARIS)
- #include <inttypes.h>
- #endif
-
- #define ERROR -1
- #define OFFSET 0x0 /* offset to preferred location */
-
- #define CALL 0xe8 /* opcode for CALL on i386 */
- #define JMP 0xeb /* opcode for JMP on i386 */
-
- bfd_format bfdformat;
- enum bfd_flavour bfdflavour;
- bfd *abfd = NULL, *abfd1 = NULL;
-
- u_long *entaddr = NULL;
- asection *asect = NULL;
-
- int offset = OFFSET;
-
- char ops[] = { (char)CALL, (char)JMP, '\0' };
-
- /* --------------------------------------- */
-
- /* ------- function declarations ------- */
- void setup();
- void showStats();
- void modSection(char *outfile, char *sectname);
-
- void bfderror(char *fmt, ...);
- /* ------------------------------------- */
-
- int main(int argc, char **argv)
- {
- if (argc <= 2)
- {
- fprintf(stderr, "Usage: %s <infile> <outfile> [addr offset]\n",
- argv[0]);
-
- exit(ERROR);
- }
-
- else if (argc > 3) offset = atoi(argv[3]);
-
- bfd_init();
- bfd_set_error_handler((bfd_error_handler_type)bfderror);
-
- abfd = bfd_openr(argv[1], NULL);
-
- setup(), showStats();
- modSection(argv[2], ".text");
-
- bfd_close(abfd);
- return 0;
- }
-
-
- void setup()
- {
- bfdformat = bfd_object;
- if (bfd_check_format(abfd, bfdformat) == false)
- {
- (void)fprintf(stderr, "error: only object files are supported\n\n");
- exit(ERROR);
- }
-
- bfdflavour = bfd_get_flavour(abfd);
- if (bfdflavour == ERROR)
- {
- bfderror("[bfd_get_flavour] error");
- exit(ERROR);
- }
-
- /* ---------------------------------------------------- */
-
- if ((bfdflavour == bfd_target_unknown_flavour) ||
- ((bfdflavour != bfd_target_aout_flavour) &&
- (bfdflavour != bfd_target_coff_flavour) &&
- (bfdflavour != bfd_target_elf_flavour)))
- {
- (void)fprintf(stderr, "Only current supported formats (flavours): "
- "ELF, COFF, and AOUT\n");
-
- exit(ERROR);
- }
- }
-
-
- void showStats()
- {
- (void)printf("Filename: %s\n\n", bfd_get_filename(abfd));
- (void)printf("File's target: %s\n", bfd_get_target(abfd));
-
- entaddr = (u_long *)bfd_get_start_address(abfd);
- (void)printf("Start address: %p\n\n", entaddr);
- }
-
-
- void modSection(char *outfile, char *sectname)
- {
- register int i;
- int sectmod = 0, sectsize = 0;
- char *sectbuf, *sectptr = NULL;
-
- asect = bfd_get_section_by_name(abfd, sectname);
- if (asect == NULL)
- {
- bfderror("[bfd_get_section_by_name] error opening %s\n", sectname);
- exit(ERROR);
- }
-
- sectsize = bfd_get_section_size_before_reloc(asect);
-
- sectbuf = (char *)malloc(sectsize+1);
- memset(sectbuf, 0, sectsize+1);
-
- if (bfd_get_section_contents(abfd, asect, sectbuf, 0, sectsize) == false)
- {
- bfderror("[bfd_get_section_contents] error opening %s section",
- sectname);
-
- exit(ERROR);
- }
-
- printf("%s size = 0x%x (%d) bytes\n\n", sectname, sectsize, sectsize);
- printf("Start (%p) - End (%p)\n", sectbuf, §buf[sectsize]);
- sleep(2);
-
- for (sectptr = sectbuf; sectptr < §buf[sectsize]; sectptr++)
- {
- for (i = 0; ops[i]; i++)
- if (*sectptr == ops[i])
- {
- printf("0x%02x found at [%s] + 0x%x\n",
- ops[i], sectname, (u_long)sectptr - (u_long)sectbuf,
- (u_long)sectptr - (u_long)sectbuf);
-
- sectptr += 1; /* 4-byte address after jmp/call opcode */
-
- /* ----------------------------------- */
-
- /*
- if (!bfd_little_endian(abfd))
- *((u_long *)sectptr) = (u_long)(entaddr + offset);
-
- else *((u_long *)sectptr) = ntohl((u_long)(entaddr + offset));
- */
-
- sectmod = 1;
- }
- }
-
- if (sectmod)
- {
- abfd1 = bfd_openw(outfile, NULL);
-
- if (abfd1 == NULL)
- {
- bfderror("[bfd_openw] error with opening %s", outfile);
- exit(ERROR);
- }
-
- bfd_copy_private_bfd_data(abfd, abfd1);
- bfd_set_section_contents(abfd1, asect, sectbuf, 0, sectsize);
-
- bfd_close(abfd1);
- }
- }
-
-
- /* our error message handler */
- void bfderror(char *fmt, ...)
- {
- va_list va;
- char errbuf[512] = {0};
-
- va_start(va, fmt);
- vsnprintf(errbuf, sizeof(errbuf)-1, fmt, va);
- va_end(va);
-
- bfd_perror(errbuf);
- }
-
-
-